home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / misc / jlem / progjlem.pas < prev   
Pascal/Delphi Source File  |  1992-12-10  |  22KB  |  555 lines

  1. {**********************************************************************}
  2. {                                                                      }
  3. { PROGRAM NAME: JLEM                                                   }
  4. { WRITTEN BY: JOHN NEMEC                                               }
  5. { DATE:   OCTOBER 1992                                                 }
  6. {                                                                      }
  7. { This PASCAL program reads an Intel hex file and sends data to the    }
  8. { ROM EMULATOR in serial format.                                       }
  9. {                                                                      }
  10. { You can quit JLEM and unplug the emulator from the PC.  The emulator }
  11. { will remain in the EMULATE mode and the target system will continue  }
  12. { to run.                                                              }
  13. {                                                                      }
  14. {**********************************************************************}
  15.  
  16. program LEM;
  17.  
  18.  
  19. type hexstr = string[4];
  20.  
  21. {**********************************************************************}
  22. {                                                                      }
  23. { FUNCTION NCON                                                        }
  24. {                                                                      }
  25. { Converts a string representing a hexadecimal number to the number    }
  26. {                                                                      }
  27. {**********************************************************************}
  28.  
  29. function ncon(hexnum: hexstr): integer;
  30.  
  31.  
  32. {**********************************************************************}
  33. {                                                                      }
  34. { FUNCTION NUMBER                                                      }
  35. {                                                                      }
  36. { Converts an ASCII character representing a hex number into an integer}
  37. {                                                                      }
  38. {**********************************************************************}
  39.  
  40. function number(hexchr: char): integer;
  41.          var temp: integer;
  42.          begin
  43.               hexchr := UpCase(hexchr);
  44.               temp := Ord(hexchr) - 48;
  45.               if (temp > 16) then begin
  46.                                        temp := temp - 7;
  47.                                        if (temp < 10) then temp := temp -10;
  48.                                        end;
  49.               if (temp > 15) then temp := -temp;
  50.               number := temp;
  51.               end;
  52.  
  53. var i,t,sum,l: integer;
  54. begin
  55. l := length(hexnum);
  56. t := 1;
  57. sum := 0;
  58. for i := 1 to l do begin
  59.                         sum := sum + t*number(hexnum[l - i + 1]);
  60.                         t := t*16;
  61.                         end;
  62. ncon := sum;
  63. end;
  64.  
  65. {                                                                      }
  66. {**********************************************************************}
  67. {                                                                      }
  68.  
  69. type name = string[80];
  70.      memarray = array[0..2047] of byte;
  71.  
  72.  
  73. {**********************************************************************}
  74. {                                                                      }
  75. { PROCEDURE INTELREAD                                                  }
  76. {                                                                      }
  77. { Reads the object code file in "INTEL HEX FORMAT", processes the      }
  78. { data, does basic checks on the data, changes the instruction code    }
  79. { from HEX to binary and stores it in the memory array.                }
  80. {                                                                      }
  81. {**********************************************************************}
  82.  
  83. procedure intelread(intelname: name; var mdata: memarray; var maxadr: integer);
  84. var
  85.    Buffer: char;
  86.    intelfile: file of char;
  87.    reclength: string[2];
  88.    addresst: string[4];
  89.    address, recint, i: integer;
  90.  
  91. label start, error, stop, cont;
  92.  
  93. {                                                                      }
  94. {**********************************************************************}
  95. {                                                                      }
  96. { OPEN THE FILE (USER ENTERS FILENAME)                                 }
  97. {                                                                      }
  98. {**********************************************************************}
  99. {                                                                      }
  100.  
  101. begin
  102.      maxadr := 0;
  103.      Assign(intelfile,intelname);
  104.      Reset(intelfile);
  105.      repeat
  106.            start:
  107.  
  108. {                                                                      }
  109. {**********************************************************************}
  110. {                                                                      }
  111. { READ RECORD MARK FIELD AND VERIFY CORRECT                            }
  112. {                                                                      }
  113. {**********************************************************************}
  114. {                                                                      }
  115.  
  116.            Read(intelfile,Buffer);
  117.            if (Buffer = ':') then goto cont;
  118.            for i := 1 to 3 do begin
  119.                               Read(intelfile,Buffer);
  120.                               if (Buffer = ':') then goto cont;
  121.                               end;
  122.            writeln('no :');
  123.            halt;
  124.  
  125. {                                                                      }
  126. {**********************************************************************}
  127. {                                                                      }
  128. { READ RECORD LENGTH FIELD AND CONVERT TO INTEGER                      }
  129. {                                                                      }
  130. {**********************************************************************}
  131. {                                                                      }
  132.  
  133.            cont:
  134.            reclength := '';
  135.            Read(intelfile,Buffer);
  136.            reclength := reclength + Buffer;
  137.            Read(intelfile,Buffer);
  138.            reclength := reclength + Buffer;
  139.            recint := ncon(reclength);
  140.            if (recint = 0) then goto stop;
  141.  
  142. {                                                                      }
  143. {**********************************************************************}
  144. {                                                                      }
  145. { READ ADDRESS FIELD AND CONVERT TO INTEGER                            }
  146. {                                                                      }
  147. {**********************************************************************}
  148. {                                                                      }
  149.  
  150.            addresst := '';
  151.            Read(intelfile,Buffer);
  152.            addresst := addresst + Buffer;
  153.            Read(intelfile,Buffer);
  154.            addresst := addresst + Buffer;
  155.            Read(intelfile,Buffer);
  156.            addresst := addresst + Buffer;
  157.            Read(intelfile,Buffer);
  158.            addresst := addresst + Buffer;
  159.            address := ncon(addresst);
  160.  
  161.  
  162. {                                                                      }
  163. {**********************************************************************}
  164. {                                                                      }
  165. { READ RECORD TYPE FIELD                                               }
  166. {                                                                      }
  167. {**********************************************************************}
  168. {                                                                      }
  169.  
  170.            reclength := '';
  171.            Read(intelfile,Buffer);
  172.            reclength := reclength + Buffer;
  173.            Read(intelfile,Buffer);
  174.            reclength := reclength + Buffer;
  175.            if (reclength <> '00') then goto stop;
  176.  
  177.  
  178. {                                                                      }
  179. {**********************************************************************}
  180. {                                                                      }
  181. { READ DATA FIELDS; REPEAT RECINT TIMES                                }
  182. {                                                                      }
  183. {**********************************************************************}
  184. {                                                                      }
  185.  
  186.            for i := 1 to recint do begin
  187.                reclength := '';
  188.                Read(intelfile,Buffer);
  189.                reclength := reclength + Buffer;
  190.                Read(intelfile,Buffer);
  191.                reclength := reclength + Buffer;
  192.                mdata[address + i -1] :=  ncon(reclength);
  193.                if ((address + i - 1) > maxadr) then maxadr := address + i - 1;
  194.                end;
  195.  
  196. {                                                                      }
  197. {**********************************************************************}
  198. {                                                                      }
  199. { READ CHECKSUM FIELD                                                  }
  200. {                                                                      }
  201. {**********************************************************************}
  202. {                                                                      }
  203.  
  204.            reclength := '';
  205.            Read(intelfile,Buffer);
  206.            reclength := reclength + Buffer;
  207.            Read(intelfile,Buffer);
  208.            reclength := reclength + Buffer;
  209.            until EOF(intelfile);
  210.            stop:
  211.      Close(intelfile);
  212. end;
  213.  
  214. {                                                                      }
  215. {**********************************************************************}
  216. {                                                                      }
  217. { TIME DELAY PROCEDURE                                                 }
  218. {                                                                      }
  219. {**********************************************************************}
  220. {                                                                      }
  221.  
  222. procedure tdly(n:integer);
  223. var i:integer;
  224. begin
  225. for i := 1 to n do;
  226. end;
  227.  
  228.  
  229. const td: integer = 10;
  230.  
  231. procedure init;
  232.  
  233. {                                                                      }
  234. {**********************************************************************}
  235. {                                                                      }
  236. { PUT THE SIMULATOR INTO THE LEARN MODE                                }
  237. { OUTPUT DATA TO PRINTER PORT 1 IN SERIAL MODE                         }
  238. {                                                                      }
  239. {**********************************************************************}
  240. {                                                                      }
  241.  
  242. var
  243.    i: integer;
  244.  
  245. begin
  246. port[634] := $20;
  247. port[632] := 2;          {DUMMY DATA TO PUT FLIP FLOP IN LEARN MODE}
  248. tdly(td);
  249. port[634] := $21;
  250. tdly(td);
  251. port[634] := $20;
  252. tdly(td);
  253. port[632] := 3;
  254. tdly(td);
  255. for i := 1 to 23 do begin
  256.     port[634] := $21;
  257.     tdly(td);
  258.     port[634] := $20;
  259.     tdly(td);
  260.     end;
  261. port[632] := 0;         {set control low  --  CLOCK LEARN/EMULATE FLIP FLOP}
  262. tdly(td);
  263. port[634] := $21;
  264. tdly(td);
  265. port[634] := $20;
  266. tdly(td);
  267. port[632] := 2;
  268. end;
  269.  
  270.  
  271.  
  272. procedure endload;
  273.  
  274. {                                                                      }
  275. {**********************************************************************}
  276. {                                                                      }
  277. { PUT THE SIMULATOR IN THE EMULATE MODE                                }
  278. { USE DUMMY DATA; DON'T WRITE TO RAM BUT PUT 1                         }
  279. { INTO FLIP FLOP TO PUT INTO EMULATE MODE                              }
  280. {                                                                      }
  281. {**********************************************************************}
  282. {                                                                      }
  283.  
  284. var
  285.    i: integer;
  286.  
  287. begin
  288. port[632] := 3;
  289. tdly(td);
  290. for i := 1 to 24 do begin
  291.     port[634] := $21;
  292.     tdly(td);
  293.     port[634] := $20;
  294.     tdly(td);
  295.     end;
  296. port[632] := 0; {set control low}
  297. tdly(td);
  298. port[634] := $21;
  299. tdly(td);
  300. port[634] := $20;
  301. tdly(td);
  302. port[632] := 2;
  303. end;
  304.  
  305.  
  306.  
  307. {                                                                      }
  308. {**********************************************************************}
  309. {                                                                      }
  310. { PROCEDURE LOADBYTE                                                   }
  311. { Loads a byte of data into the memory at a specified address          }
  312. {                                                                      }
  313. {**********************************************************************}
  314. {                                                                      }
  315.  
  316.  
  317. procedure loadbyte(data: byte; address: integer);
  318.  
  319. var
  320.    adrcont, i: integer;
  321.    out: byte;
  322. begin
  323.  
  324. {                                                                      }
  325. {**********************************************************************}
  326. {                                                                      }
  327. { Bit 0 of port [634] is clock (STROBE)                                }
  328. { Bit 0 of port [632] is data and bit 1 is control                     }
  329. {                                                                      }
  330. {**********************************************************************}
  331. {                                                                      }
  332.  
  333. adrcont := address AND $0FFF;
  334. for i := 15 downto 0 do begin
  335.     out := $02 OR ((adrcont SHR i) AND $01);  {SERIALIZES INTEGER ADDRESS}
  336.     port[632] := out;
  337.     port[634] := $21;
  338.     tdly(td);
  339.     port[634] := $20;
  340.     end;
  341. for i := 7 downto 0 do begin
  342.     out := $02 OR ((data SHR i) AND $01);  {SERIALIZES BYTE (INSTRUCTION)}
  343.     port[632] := out;
  344.     port[634] := $21;
  345.     tdly(td);
  346.     port[634] := $20;
  347.     end;
  348. port[632] := 0;      {SET CONTROL LOW}
  349. tdly(td);
  350. port[634] := $21;      {STROBE INTO MEMORY}
  351. tdly(td);
  352. port[634] := $20;
  353. tdly(td);
  354. port[632] := 2;
  355. end;
  356.  
  357.  
  358.  
  359. {                                                                      }
  360. {**********************************************************************}
  361. {                                                                      }
  362. { FUNCTION TEST                                                        }
  363. { Test to see if HEXNUM is valid hexadecimal number                    }
  364. { Lower case is assumed                                                }
  365. {                                                                      }
  366. {**********************************************************************}
  367. {                                                                      }
  368.  
  369. function test(hexnum: hexstr): boolean;
  370. var i: integer;
  371.     temp,temp1: boolean;
  372.     tempch: char;
  373.  
  374. begin
  375. temp1 := TRUE;
  376. for i := 1 to length(hexnum) do begin
  377.     tempch := UpCase(hexnum[i]);
  378.     case tempch of
  379.          '0': temp := TRUE;
  380.          '1': temp := TRUE;
  381.          '2': temp := TRUE;
  382.          '3': temp := TRUE;
  383.          '4': temp := TRUE;
  384.          '5': temp := TRUE;
  385.          '6': temp := TRUE;
  386.          '7': temp := TRUE;
  387.          '8': temp := TRUE;
  388.          '9': temp := TRUE;
  389.          'A': temp := TRUE;
  390.          'B': temp := TRUE;
  391.          'C': temp := TRUE;
  392.          'D': temp := TRUE;
  393.          'E': temp := TRUE;
  394.          'F': temp := TRUE;
  395.          else temp := FALSE;
  396.     end;
  397.     temp1 := temp1 AND temp;
  398.     test := temp1;
  399.     end;
  400. end;
  401.  
  402.  
  403. {                                                                      }
  404. {**********************************************************************}
  405. {                                                                      }
  406. { PROCEDURE HEXCHG                                                     }
  407. { Converts a number into the HEX representation as a string            }
  408. {                                                                      }
  409. {**********************************************************************}
  410. {                                                                      }
  411.  
  412. procedure hexchg(numin: integer; var hexnum: hexstr);
  413. {converts a number into the Hex representation as a string}
  414. var ch: string[1];
  415.     temp,i: integer;
  416. begin
  417.      hexnum := '';
  418.      for i := 4 downto 1 do begin
  419.          temp := (numin SHR (4*(i-1)) AND $000F);
  420.          if (temp > 9) then temp := temp + 55 else temp := temp + 48;
  421.          ch := Chr(temp);
  422.          hexnum := hexnum + ch;
  423.          end;
  424. end;
  425.  
  426. {                                                                      }
  427. {**********************************************************************}
  428. {                                                                      }
  429. { MAIN PROGRAM BEGINS HERE                                             }
  430. {                                                                      }
  431. {**********************************************************************}
  432. {                                                                      }
  433.  
  434. var
  435.    address, times, maxadr: integer;
  436.    memory: memarray;
  437.    cmd: char;
  438.    hadr,prhex,memhex: hexstr;
  439.    fname: name;
  440.  
  441. label input1, input2, cycle1, cycle2, reread, reload, command;
  442.  
  443. begin
  444. LowVideo;
  445. for address := 0 to 2047 do memory[address] := 0;
  446. write('Enter Intel hex code file name: ');
  447. readln(fname);
  448. if (Pos('.',fname) = 0) then fname := fname + '.hex';
  449. intelread(fname,memory,maxadr);
  450. reload:
  451. init;
  452. if (maxadr > 2047) then writeln('Warning program exceeds simulator memory.');
  453. writeln('Loading Simulator Module.');
  454.  
  455. {                                                                      }
  456. {**********************************************************************}
  457. {                                                                      }
  458. { CALL "LOADBYTE" TO SEND BYTE AT A TIME WITH ADDRESS                  }
  459. {                                                                      }
  460. {**********************************************************************}
  461. {                                                                      }
  462.  
  463. for address := 0 to maxadr do loadbyte(memory[address],address);
  464. endload;          {PUT IN EMULATE MODE}
  465. writeln('Simulation mode.');
  466. command: writeln;
  467. read(KBD, cmd);          {ACCEPT USER COMMAND}
  468. cmd := UpCase(cmd);
  469. case cmd of
  470.      'D': goto input2;     {"D"ISPLAY MEMORY CONTENTS IN HEX ON SCREEN}
  471.      'C': goto input1;      {"C"HANGE A BYTE}
  472.      'R': goto reload;       {"R"ELOAD ENTIRE EMULATION RAM}
  473.      'Q': halt;                   {"Q"UIT --  RETURN TO DOS}
  474.      else goto command;
  475.      end;
  476.  
  477. {                                                                      }
  478. {**********************************************************************}
  479. {                                                                      }
  480. { CHANGE MEMORY                                                        }
  481. {                                                                      }
  482. {**********************************************************************}
  483. {                                                                      }
  484.  
  485. input1: write('C: ');
  486. readln(hadr);
  487. if (NOT test(hadr)) then goto input1;
  488. address := ncon(hadr);
  489. cycle1: hexchg(address, prhex);
  490. hexchg(memory[address], memhex);
  491. Delete(memhex, 1,2);
  492. write(prhex,': ',memhex,'  ');
  493. reread:
  494. read(KBD, cmd);
  495.  
  496. {                                                                      }
  497. {**********************************************************************}
  498. {                                                                      }
  499. { IF "SPACEBAR" IS PRESSED DON'T CHANGE; INCR ADDRESS                  }
  500. {                                                                      }
  501. {**********************************************************************}
  502. {                                                                      }
  503.  
  504. if (cmd = '') then begin
  505.                     address := address + 1;
  506.                     writeln;
  507.                     goto cycle1;
  508.                     end;
  509. if (cmd = #13) then goto command;
  510. write(cmd);
  511.  
  512. readln(memhex);     {ENTER NEW BYTE TO BE PLACED AT ADDRESS}
  513. memhex := cmd + memhex;
  514. if ((NOT test(memhex)) OR (Length(memhex) > 2)) then goto reread;
  515. memory[address] := ncon(memhex);
  516. init;                         {PUT IN LEARN MODE}
  517. loadbyte(memory[address], address);     {SEND ADDRESS & BYTE}
  518. endload;                    {PUT IN EMULATE MODE}
  519. hexchg(memory[address], memhex);
  520. Delete(memhex, 1,2);
  521. writeln(prhex,': ',memhex,'  ');
  522. if (address < 2047) then address := address +1 else address :=0;
  523. goto cycle1;
  524. goto command;
  525.  
  526.  
  527.  
  528. {                                                                      }
  529. {**********************************************************************}
  530. {                                                                      }
  531. { DISPLAY MEMORY                                                       }
  532. { Converts MEMARRAY into HEX so you can read it and puts it on the     }
  533. { screen.                                                              }
  534. {                                                                      }
  535. {**********************************************************************}
  536. {                                                                      }
  537.  
  538. input2: write('D: ');
  539. readln(hadr);
  540. if (NOT test(hadr)) then goto input2;
  541. address := ncon(hadr);
  542. times := 0;
  543. cycle2: times := times + 1;
  544. hexchg(address, prhex);
  545. hexchg(memory[address], memhex);
  546. Delete(memhex, 1,2);
  547. write(prhex,': ',memhex,'  ');
  548. if ((address < 2046) AND (times < 128)) then begin
  549.                                              address := address + 1;
  550.                                              goto cycle2;
  551.                                              end;
  552. writeln;
  553. goto command;
  554. end.
  555.